package byx.container.annotation.extension.impl;

import byx.container.annotation.annotation.Order;
import byx.container.annotation.exception.UnsupportedCollectionTypeException;
import byx.container.annotation.extension.core.ParameterHandler;
import byx.container.annotation.extension.core.ParameterInfo;
import byx.container.core.Container;
import byx.container.core.ObjectFactory;
import byx.container.core.utils.CastUtils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;

import static byx.container.core.ObjectFactories.allFromContainer;

/**
 * 集合类型参数处理器
 */
@Order(Integer.MAX_VALUE - 1)
public class CollectionParameterHandler implements ParameterHandler {
    @Override
    public boolean support(ParameterInfo param) {
        return Collection.class.isAssignableFrom(param.getParameterType());
    }

    @Override
    public ObjectFactory<?> handle(ParameterInfo param, Container container) {
        Class<?> collectionType = param.getParameterType();
        Type geneticType = param.getGeneticParameterType();

        try {
            Type typeArgument = ((ParameterizedType) geneticType).getActualTypeArguments()[0];
            Class<?> elemType;
            if (typeArgument instanceof Class) {
                elemType = (Class<?>) typeArgument;
            } else {
                elemType = (Class<?>) ((ParameterizedType) typeArgument).getRawType();
            }
            return allFromContainer(container, elemType)
                    .map(CastUtils.cast(CollectionConverter.converter(collectionType)));
        } catch (Exception e) {
            throw new UnsupportedCollectionTypeException(geneticType, e);
        }
    }
}
